package com.designoutput.ui.newControls
{
	import com.designoutput.manager.ValidationManager;
	import com.designoutput.utils.Globals;
	
	import flash.display.Sprite;
	
	public class ControlBaseMain extends Sprite
	{
		private var _isInvalid:Boolean = false;
		private var _invalidDisplay:Boolean = false;
		private var _invalidProperties:Boolean = false;
		protected var _width:Number = Number.NaN;
		protected var _height:Number = Number.NaN;
		
		protected var initialized:Boolean = false;
		
		public function ControlBaseMain()
		{
			initialize();
			invalidate();
		}
		
		/**
		 * Initialize control children and properties 
		 */		
		protected function initialize():void {
			initialized = true;
		}

		/**
		 * Indicate if a control is on an invalid state
		 */		
		public function get isInvalid():Boolean {
			return _isInvalid;
		}
		
		protected function invalidateProperties():void {
			if(!_invalidProperties){
				_invalidProperties = true;
				invalidate();
			}
		}
		
		/**
		 * Mark control layout as invalid, so layoutChildren will be called on next validation 
		 */		
		protected function invalidateDisplay():void {
			if(!_invalidDisplay){
				_invalidDisplay = true;
				invalidate();
			}
		}

		/**
		 * Mark that the controls is invalid, and queue the validation
		 */		
		private function invalidate():void {
			if(!_isInvalid){
				_isInvalid = true;
				Globals.validationManager.queueValidation(this);
			}
		}
		
		/**
		 * Validate control state.
		 */		
		public function validate():void {
			_isInvalid = false;
			
			if(_invalidProperties){
				_invalidProperties = false;
				commitProperties();
			}
			
			if(_invalidDisplay){
				_invalidDisplay = false;
				updateDisplay();
			}
		}
		
		protected function commitProperties():void {
			
		}
		
		/**
		 * Layout the children controls
		 */		
		protected function updateDisplay():void {
		}

		protected function get minWidth():Number {
			return 0;
		}
		
		protected function get minHeight():Number {
			return 0;
		}
		
		override public function get width():Number {
			if(isNaN(_width))
				return super.width
			
			return _width;
		}
		override public function set width(value:Number):void {
			if(_width != value){
				_width = value;
				if(!isNaN(_width)){
					_width = Math.round(_width);
					if(_width < minWidth)
						_width = minWidth;
				}
				
				invalidateDisplay();
			}
		}
				
		override public function get height():Number {
			 if(isNaN(_height))
				 return super.height; 
				 
			 return _height;
		}
		override public function set height(value:Number):void {
			if(_height != value){
				_height = value;
				if(!isNaN(_height)){
					_height = Math.round(_height);
					if(_height < minHeight)
						_height = minHeight;
				}
				
				invalidateDisplay();
			}
		}
	}
}